package fun.flyee.android.pengshan.fgts;


import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;

import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.ConsoleMessage;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.widget.FrameLayout;

import org.greenrobot.eventbus.Subscribe;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import butterknife.BindView;
import cn.bingoogolapple.photopicker.activity.BGAPhotoPickerActivity;
import fun.flyee.android.pengshan.Constant;
import fun.flyee.android.pengshan.acts.MainActivity;
import fun.flyee.android.pengshan.acts.Router;
import fun.flyee.android.pengshan.api.JsBridge;
import fun.flyee.android.pengshan.events.GetConferenceEvent;
import fun.flyee.android.pengshan.utils.PathUtil;
import fun.flyee.android.pengshan.utils.Systems;
import fun.flyee.android.pengshan.widgets.Tips;
import fun.flyee.pengshan.social.R;
import fun.flyee.android.pengshan.api.ApiClient;
import fun.flyee.android.pengshan.events.WebEvent;
import fun.flyee.android.pengshan.utils.Files;
import fun.flyee.android.pengshan.utils.Logger;
import fun.flyee.android.pengshan.widgets.ExWebView;

import static android.app.Activity.RESULT_OK;

public class WebFragment extends BaseFragment {

//    public final static String HTTP_SERVER = "local";
//    public final static String HTTP_SERVER = "http://192.168.31.133:8080/";

    protected static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

    @BindView(R.id.web_view)
    public ExWebView mWebView;
    public CustomChromeClient mChromeClient;
    public JsBridge mBridge;

    private String path;
    private String query;
    private String payload;

    public WebFragment() {

    }

    public static WebFragment newInstance(String path, String query) {
        WebFragment fragment = new WebFragment();
        fragment.path = path;
        fragment.query = query;
        return fragment;
    }

    public static WebFragment newInstance2(String path, String payload) {
        WebFragment fragment = new WebFragment();
        fragment.path = path;
        fragment.payload = payload;
        return fragment;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public void setQuery(String query) {
        this.query = query;
    }

    public void setPayload(String payload) {
        this.payload = payload;
    }

    protected int layoutId() {
        return R.layout.fgt_web;
    }

    @Override
    public void onResume() {
        super.onResume();
        try {
            if (getActivity() != null && getActivity() instanceof MainActivity && mBridge != null) {
                mBridge.callJs("onActivityResume");
            }
        } catch (Exception e) {
            Logger.e("error", e);
        }
    }

    public void onBackPressed() {
        if (mChromeClient.customView != null) {
            mChromeClient.onHideCustomView();
        } else if (mBridge != null) {
            mBridge.callJs("onBackPressed");
        }
    }

    @Override
    protected void initView() {
        mWebView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        mWebView.clearCache(true);
        mWebView.setBackgroundColor(Color.WHITE);
        mWebView.requestFocus();
        mWebView.setClickable(true);
        mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        mWebView.getSettings().setAppCacheEnabled(true);
        mWebView.getSettings().setSavePassword(false);
        mWebView.getSettings().setSaveFormData(false);
        mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        mWebView.getSettings().setUseWideViewPort(true);
        mWebView.getSettings().setAllowFileAccess(true);
        mWebView.getSettings().setAllowContentAccess(true);
        mWebView.getSettings().setAllowFileAccessFromFileURLs(true);
        mWebView.getSettings().setAllowUniversalAccessFromFileURLs(true);
        mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        mWebView.getSettings().setLoadWithOverviewMode(true);
        mWebView.setGeolocationEnabled(true);
        mWebView.setMixedContentAllowed(true);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.setCookiesEnabled(true);
        mWebView.setThirdPartyCookiesEnabled(true);
        mWebView.addHttpHeader("X-Requested-With", "");
        mWebView.setListener(getActivity(), new ExWebView.Listener() {
            @Override
            public void onPageStarted(String url, Bitmap favicon) {
                Logger.i("start load : " + url + "   ");
            }

            @Override
            public void onPageFinished(String url) {
                Logger.i("finish load : " + url + "   ");
            }

            @Override
            public void onPageError(int errorCode, String description, String failingUrl) {
                Logger.e(errorCode + ":" + description + " - " + failingUrl);
            }

            @Override
            public void onDownloadRequested(String url, String suggestedFilename, String mimeType, long contentLength, String contentDisposition, String userAgent) {
                Logger.i("webview download : " + url + "   ");
            }

            @Override
            public void onExternalPageRequest(String url) {

            }

            @Override
            public void onViewSizeChanged(int nw, int nh, int ow, int oh) {
                if (path != null && path.contains("/location/picker")) {
                    if (getActivity() == null || mBridge == null) return;
                    mBridge.callJs("triggerSearchLayout", oh, nh);
                }
            }
        }, Constant.INTENT_REQUEST_PHOTO_CHOOSE);
        mChromeClient = new CustomChromeClient();
        mWebView.setWebChromeClient(mChromeClient);
        mBridge = new JsBridge(this, payload);
        mWebView.addJavascriptInterface(mBridge, "bridge");
        mWebView.loadUrl(getUrl());
    }

    private String getUrl() {
        String url;
        if (Constant.WEB_URL.equals("local")) {
            File folder = new File(getContext().getFilesDir(), "ui");
            Uri uri = Uri.fromFile(new File(folder, "index.html"));
            url = uri.toString();
        } else {
            url = Constant.WEB_URL;
        }
        url += "#" + path + (TextUtils.isEmpty(query) ? "" : "?" + query);
        return url;
    }

    @Override
    protected void initData() {
    }

    @Override
    public void onDestroy() {
        if (mBridge != null) {
            mBridge.destroy();
            mBridge = null;
        }
        if (mWebView != null) {
            try {
                if (mWebView.getParent() != null) {
                    ((ViewGroup) mWebView.getParent()).removeView(mWebView);
                }
                mWebView.setVisibility(View.GONE);
                mWebView.removeAllViews();
                mWebView.loadUrl("about:blank");
                mWebView.freeMemory();
                if (mWebView.isActivated()) mWebView.destroy();
            } catch (IllegalArgumentException e) {
                Logger.e(e.getMessage());
            }
            mWebView = null;
        }
        super.onDestroy();
    }

    @Subscribe
    public void onWebEvent(WebEvent ev) {
        if (getActivity() == null || mBridge == null) return;
        mBridge.callJs("handleEvent", "\"" + ev.name + "\"", ev.payload);
    }

    @Subscribe
    public void onConferenceLoad(GetConferenceEvent ev) {
        getActivity().runOnUiThread(() -> {
            mBridge.callJs("onConference", ev.json);
        });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (mWebView != null) {
            if (requestCode == Constant.INTENT_REQUEST_LOCATION && resultCode == RESULT_OK) {
                double lat = intent.getDoubleExtra("lat", 0d);
                double lng = intent.getDoubleExtra("lng", 0d);
                String addr = intent.getStringExtra("addr");
                if (mBridge != null) {
                    mBridge.callJs("onLocation", lat, lng, "\"" + addr + "\"");
                }
            } else if (requestCode == Constant.INTENT_REQUEST_RESULT && resultCode == RESULT_OK) {
                String data = intent.getStringExtra("data");
                mBridge.callJs("dataFromNative", data);
            } else if (requestCode == Constant.INTENT_REQUEST_SCAN_QRCODE && resultCode == RESULT_OK) {
                String data = intent.getStringExtra("data");
                Router.go(getContext(), "/city/advert/tablet/detail", "id=" + data.substring(data.indexOf("=") + 1));
            } else if (requestCode == Constant.INTENT_REQUEST_VIDEO_CHOOSE && resultCode == RESULT_OK) {
                if (intent != null) {
                    Uri uri = intent.getData();
                    String path = PathUtil.getFileResultPath(getContext(), uri);
                    File file = new File(path);
                    if (file.exists()) {
                        mBridge.callJs("busy");
                        ApiClient.upload(file, result -> {
                            mBridge.callJs("free");
                            if (result.code == 200) {
                                mBridge.callJs("onPickVideo", result.data.toString());
                            } else {
                                Tips.toast(result.msg);
                            }
                        });
                    }
                }
            } else {
                mWebView.onActivityResult(requestCode, resultCode, intent);
            }
        }
    }

    static class FullscreenHolder extends FrameLayout {

        public FullscreenHolder(Context ctx) {
            super(ctx);
            setBackgroundColor(ctx.getResources().getColor(android.R.color.black));
        }

        @Override
        public boolean onTouchEvent(MotionEvent evt) {
            return true;
        }
    }

    class CustomChromeClient extends WebChromeClient {

        private View customView;
        private android.webkit.WebChromeClient.CustomViewCallback customViewCallback;
        private FullscreenHolder fullscreenContainer;

        public boolean onConsoleMessage(ConsoleMessage cm) {
            Logger.i("Console", cm.message() + " -- From line "
                    + cm.lineNumber() + " of "
                    + cm.sourceId());
            return true;
        }

        public View getVideoLoadingProgressView() {
            FrameLayout frameLayout = new FrameLayout(getContext());
            frameLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
            return frameLayout;
        }

        @Override
        public void onShowCustomView(View view, android.webkit.WebChromeClient.CustomViewCallback callback) {
            if (customView != null) {
                callback.onCustomViewHidden();
                return;
            }

            getActivity().getWindow().getDecorView();

            FrameLayout decor = (FrameLayout) getActivity().getWindow().getDecorView();
            fullscreenContainer = new FullscreenHolder(getContext());
            fullscreenContainer.addView(view, COVER_SCREEN_PARAMS);
            decor.addView(fullscreenContainer, COVER_SCREEN_PARAMS);
            customView = view;
            Systems.hideSystemStatusBar(getActivity());
            customViewCallback = callback;
        }

        @Override
        public void onHideCustomView() {
            if (customView == null) {
                return;
            }

            Systems.showSystemStatusBar(getActivity());
            FrameLayout decor = (FrameLayout) getActivity().getWindow().getDecorView();
            decor.removeView(fullscreenContainer);
            fullscreenContainer = null;
            customView = null;
            customViewCallback.onCustomViewHidden();
            mWebView.setVisibility(View.VISIBLE);
        }
    }
}
